The Perl Apps as Modules Paradigm

Shlomi Fish on 2007-09-09T16:37:37

Back at the time when I was uploading new versions of Test::Run::CmdLine, I found out that some CPAN testers report were failing because one of the scripts that was supposed to be installed by a dependency, and was used in a test, was not available in the path.

My solution to this was to make sure the script just called the "run()" function of a module, and then to invoke the module in the tests from the command line like this:

perl -MApp::MyApp -e 'run()' -- --name "Sophie"

App::MyApp can be something like:

package App::MyApp;

use strict;
use warnings;

use base 'Exporter';

our @EXPORT=(qw(run));

use Getopt::Long;

sub run
{
    my $name = "World";

    GetOptions("name=s" => \$name);

    print "Hello, $name!\n";
}

1;

It's also useful to be able to run such programs without needing to install scripts and with just dependence on the Perl module's path.

On my homepage makefile, I have the following rules to handle the Screenplays:

lib/docbook/xml/%.xml: lib/screenplay-xml/xml/%.xml
	perl -MXML::Grammar::Screenplay::App::ToDocBook -e 'run()' -- \
	-o $@ $<

lib/screenplay-xml/html/%.html: lib/screenplay-xml/xml/%.xml
	perl -MXML::Grammar::Screenplay::App::ToHTML -e 'run()' -- \
	-o $@ $<

lib/screenplay-xml/xml/%.xml: lib/screenplay-xml/txt/%.txt
	perl -MXML::Grammar::Screenplay::App::FromProto -e 'run()' -- \
	-o $@ $<

This solves me the problem of depending on the scripts being in the path.


My scripts

Alias on 2007-09-09T23:13:25

#!/usr/bin/perl

use strict;
use App::Name;

App::Name::main(@ARGV);